import java.util.ArrayList;

public class ListView extends View implements ScrollBarDelegate, ListViewRowDelegate {
	public final static int ROW_OFFSET = 3;
	public final static int ROW_HEIGHT = 35;
	private int nCols;
	private float colWidth;
	private ArrayList<ListViewRow> rows;
	private ScrollBar bar;
	private ArrayList< ArrayList<String>> info;
	private ListViewDelegate delegate;
	private int selectedInfo;
	
	/*=============================================================================================
	 * Constructor
	 *-------------------------------------------------------------------------------------------*/
	public ListView(float x_, float y_, float pColWidth, int pNRows, int pNCols, MainView p) {
		super(	x_,
				y_,
				pColWidth*pNCols+ScrollBar.WIDTH+3*ROW_OFFSET,
				ROW_HEIGHT*(pNRows+1)+ROW_OFFSET*(pNRows+2),
				p);
		
		delegate = null;
		colWidth = pColWidth;
		nCols = pNCols;
		info = new ArrayList<ArrayList<String>>();
		rows = new ArrayList<ListViewRow>();
		selectedInfo = -1;
		
		ListViewRow newRow;
		float rowWidth = colWidth*nCols; 
		
		for( int i=0; i<pNRows+1; i++)
		{
			newRow = new ListViewRow(	ROW_OFFSET,
										ROW_OFFSET+(ROW_HEIGHT+ROW_OFFSET)*i,
										rowWidth,
										ROW_HEIGHT,
										nCols,
										p);
			newRow.setId(i);
			if( i>0) newRow.setDelegate(this);
			rows.add(newRow);
			subviews.add(newRow);
		}
		rows.get(0).setColor(255,255,255);
		rows.get(0).enable();
		
		bar = new ScrollBar(2*ROW_OFFSET+rowWidth,
							2*ROW_OFFSET+ROW_HEIGHT,
							ROW_HEIGHT*pNRows + ROW_OFFSET*(pNRows-1),
							p);
		//bar.setLevels(20);
		bar.setDelegate(this);
		
		subviews.add(bar);
		updateView();
	}
	
	/*=============================================================================================
	 * 
	 *-------------------------------------------------------------------------------------------*/
	boolean contentMouseWheel(float px, float py, int delta)
	{
		int buttonId = (delta<0) ? (ScrollBar.BTNUP_ID) : (ScrollBar.BTNDOWN_ID);
		bar.RectangularButtonPressed(buttonId);
		return true;
	}

	/*=============================================================================================
	 * 
	 *-------------------------------------------------------------------------------------------*/
	public void levelChanged(int newLevel) {
		updateView();
	}
	
	/*=============================================================================================
	 * 
	 *-------------------------------------------------------------------------------------------*/
	public void setDelegate( ListViewDelegate pDelegate) { delegate = pDelegate; }
	
	/*=============================================================================================
	 * 
	 *-------------------------------------------------------------------------------------------*/
	public void add( ArrayList<String> newInfo)
	{
		info.add( newInfo);
		if( info.size()>rows.size()-1)
			bar.setLevels( bar.getLevels() + 1);
		bar.toBottom();
		updateView();
	}
	
	/*=============================================================================================
	 * 
	 *-------------------------------------------------------------------------------------------*/
	public void setTitle( int col, String title)
	{
		rows.get(0).setCaption(col, title);
	}
	
	/*=============================================================================================
	 * 
	 *-------------------------------------------------------------------------------------------*/
	public ArrayList<String> getInfo( int infoIdx)
	{
		if( infoIdx<0 || infoIdx>=info.size())
			return null;
		else
			return info.get(infoIdx);
	}
	
	/*=============================================================================================
	 * 
	 *-------------------------------------------------------------------------------------------*/
	public void removeInfo( int infoIdx)
	{
		if( infoIdx<0 || infoIdx>=info.size()) return;

		info.remove(infoIdx);
		bar.setLevels( bar.getLevels()-1);
		if( selectedInfo == infoIdx)
		{
			selectedInfo = -1;
			if( delegate != null) delegate.infoUnselected();
		}
		else if( selectedInfo > infoIdx)
			selectedInfo--;
		
		updateView();
	}
	
	/*=============================================================================================
	 * 
	 *-------------------------------------------------------------------------------------------*/
	public int getSelectedIdx( ) { return selectedInfo; }
	
	/*=============================================================================================
	 * 
	 *-------------------------------------------------------------------------------------------*/
	void drawContent()
	{
		parent.fill(255);
		parent.noStroke();
		parent.rect(0, 0, w, h);
	}

	/*=============================================================================================
	 * 
	 *-------------------------------------------------------------------------------------------*/
	public void ListViewRowPressed(ListViewRow o) {
		//if( rowDelegate != null) rowDelegate.ListViewRowPressed(o);
		int infoIdx = bar.getCurrentLevel()+o.getId()-2;
		
		if( infoIdx == selectedInfo)
			selectedInfo = -1;
		else
			selectedInfo = infoIdx;
		
		if( delegate != null)
		{
			if( selectedInfo >= 0)
				delegate.infoSelected();
			else
				delegate.infoUnselected();
		}
		
		updateView();
	}

	/*=============================================================================================
	 * 
	 *-------------------------------------------------------------------------------------------*/
	private void updateView()
	{
		int i;
		int rowsPtr;
		int infoPtr;
		int start = bar.getCurrentLevel()-1;
		int end = start+rows.size()-1;
		if( end > info.size()) end = info.size();
		
		ArrayList<String> captions;
		ListViewRow row;
		for( rowsPtr=1, infoPtr=start; infoPtr<end; infoPtr++, rowsPtr++)
		{
			row = rows.get(rowsPtr);
			row.enable();
			captions = info.get(infoPtr);
			if( selectedInfo == infoPtr)
				row.select();
			else
				row.unSelect();
			
			for( i=0; i<captions.size(); i++) row.setCaption(i, captions.get(i));
			for( ; i<nCols; i++) row.setCaption(i, "");
		}
		
		for( ; rowsPtr<rows.size(); rowsPtr++)
		{
			row = rows.get(rowsPtr);
			row.unSelect();
			row.disable();
			for( i=0; i<nCols; i++) row.setCaption(i, "");
		}
	}

}
